﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using YanZhiwei.DotNet2.Utilities.Common;
namespace YanZhiwei.DotNet2.Utilities.Base
{
    /// <summary>
    /// IList的线程的实现的帮助类
    ///<para>参考: http://www.codeproject.com/KB/cs/safe_enumerable.aspx </para> 
    /// </summary>
    public class ThreadSafeList<T> : IList<T>
    {
        #region 构造函数以及变量
        // the (thread-unsafe) collection that actually stores everything
        private readonly List<T> _inner;
        // this is the object we shall lock on.
        private readonly object _lock = new object();
        /// <summary>
        /// ThreadSafeList构造函数
        /// </summary>
        public ThreadSafeList()
        {
            _inner = new List<T>();
        }
        /// <summary>
        /// ThreadSafeList构造函数
        /// </summary>
        /// <param name="self"></param>
        public ThreadSafeList(IEnumerable<T> self)
        {
            _inner = self.ConvertToList();
        }
        /// <summary>
        /// Count
        /// </summary>
        public int Count
        {
            get
            {
                lock (_lock)
                {
                    return _inner.Count;
                }
            }
        }
        /// <summary>
        /// IsReadOnly
        /// </summary>
        public bool IsReadOnly
        {
            get { return false; }
        }
        #endregion
        #region this线程安全
        /// <summary>
        /// this线程安全
        /// </summary>
        /// <param name="index">index</param>
        /// <returns>T</returns>
        public T this[int index]
        {
            get
            {
                lock (_lock)
                {
                    return _inner[index];
                }
            }
            set
            {
                lock (_lock)
                {
                    _inner[index] = value;
                }
            }
        }
        #endregion
        #region GetEnumerator
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            lock (_lock)
            {
                // instead of returning an usafe enumerator,
                // we wrap it into our thread-safe class
                return new ThreadSafeEnumerator<T>(_inner.GetEnumerator(), _lock);
            }
        }
        #endregion
        #region 添加
        /// <remarks>
        /// 添加
        /// </remarks>
        public void Add(T item)
        {
            lock (_lock)
            {
                _inner.Add(item);
            }
        }
        #endregion
        #region 移出所有元素
        /// <summary>
        /// 移出所有元素
        /// </summary>
        public void Clear()
        {
            lock (_lock)
            {
                _inner.Clear();
            }
        }
        #endregion
        #region 是否包含某项元素
        /// <summary>
        /// 是否包含某项元素
        /// </summary>
        /// <param name="item">item</param>
        /// <returns>是否包含</returns>
        public bool Contains(T item)
        {
            lock (_lock)
            {
                return _inner.Contains(item);
            }
        }
        #endregion
        #region 复制到某个类型数组
        /// <summary>
        /// 复制到某个类型数组
        /// </summary>
        /// <param name="array">复制到苏族</param>
        /// <param name="arrayIndex">开始位置</param>
        public void CopyTo(T[] array, int arrayIndex)
        {
            lock (_lock)
            {
                _inner.CopyTo(array, arrayIndex);
            }
        }
        #endregion
        #region 移除
        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="item">需要移除项</param>
        /// <returns>是否移除成功</returns>
        public bool Remove(T item)
        {
            lock (_lock)
            {
                return _inner.Remove(item);
            }
        }
        #endregion
        #region GetEnumerator
        /// <summary>
        /// GetEnumerator
        /// </summary>
        /// <returns>IEnumerator</returns>
        public IEnumerator GetEnumerator()
        {
            lock (_lock)
            {
                return new ThreadSafeEnumerator<T>(_inner.GetEnumerator(), _lock);
            }
        }
        #endregion
        #region IndexOf
        /// <summary>
        /// IndexOf
        /// </summary>
        /// <param name="item">索引项</param>
        /// <returns>索引位置</returns>
        public int IndexOf(T item)
        {
            lock (_lock)
            {
                return _inner.IndexOf(item);
            }
        }
        #endregion
        #region 插入一项
        /// <summary>
        /// 插入一项
        /// </summary>
        /// <param name="index">插入位置</param>
        /// <param name="item">插入项</param>
        public void Insert(int index, T item)
        {
            lock (_lock)
            {
                _inner.Insert(index, item);
            }
        }
        #endregion
        #region RemoveAt
        /// <summary>
        /// RemoveAt
        /// </summary>
        /// <param name="index">index</param>
        public void RemoveAt(int index)
        {
            lock (_lock)
            {
                _inner.RemoveAt(index);
            }
        }
        #endregion
        #region RemoveAll
        /// <summary>
        /// RemoveAll
        /// </summary>
        /// <param name="match">Predicate委托</param>
        public void RemoveAll(Predicate<T> match)
        {
            if (match != null)
            {
                lock (_lock)
                {
                    _inner.RemoveAll(match);
                }
            }
        }
        #endregion
        #region AsReadOnly
        /// <summary>
        /// AsReadOnly
        /// </summary>
        /// <returns>ReadOnlyCollection</returns>
        public ReadOnlyCollection<T> AsReadOnly()
        {
            lock (_lock)
            {
                return new ReadOnlyCollection<T>(this);
            }
        }
        #endregion
        #region ForEach
        /// <summary>
        /// ForEach
        /// </summary>
        /// <param name="action">委托</param>
        public void ForEach(Action<T> action)
        {
            if (action != null)
            {
                lock (_lock)
                {
                    foreach (var item in _inner)
                    {
                        action(item);
                    }
                }
            }
        }
        #endregion
        #region Exists
        /// <summary>
        /// Exists
        /// </summary>
        /// <param name="match">委托</param>
        /// <returns>是否存在</returns>
        public bool Exists(Predicate<T> match)
        {
            if (match != null)
            {
                lock (_lock)
                {
                    foreach (var item in _inner)
                    {
                        if (match(item))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        #endregion
        #region FindAll
        /// <summary>
        /// FindAll
        /// </summary>
        /// <param name="match">委托</param>
        /// <returns>查找到的集合</returns>
        public List<T> FindAll(Predicate<T> match)
        {
            if (match != null)
            {
                lock (_lock)
                {
                    return _inner.FindAll(match);
                }
            }
            return null;
        }
        #endregion
        #region Find
        /// <summary>
        /// Find
        /// </summary>
        /// <param name="match">委托</param>
        /// <returns>查找到项</returns>
        public T Find(Predicate<T> match)
        {
            if (match != null)
            {
                lock (_lock)
                {
                    return _inner.Find(match);
                }
            }
            return default(T);
        }
        #endregion
        #region TrimExcess
        /// <summary>
        /// TrimExcess
        /// </summary>
        public void TrimExcess()
        {
            lock (_lock)
            {
                _inner.TrimExcess();
            }
        }
        #endregion 
        #region 去重复集合添加
        /// <summary>
        /// 去重复集合添加
        /// </summary>
        /// <param name="items">添加集合</param>
        /// <param name="comparaer">IComparer</param>
        public void AddUniqueTF(IEnumerable<T> items, IComparer<T> comparaer)
        {
            lock (_lock)
            {
                _inner.Sort(comparaer);
                foreach (T item in items)
                {
                    int _result = _inner.BinarySearch(item, comparaer);//搜索前需要排序
                    if (_result < 0)
                        _inner.Add(item);
                }
            }
        }
        #endregion
        #region 先判断是否存在集合里面，若存在则移出，然后重新添加
        /// <summary>
        /// 先判断是否存在集合里面，若存在则移出，然后重新添加
        ///<para>eg:personList.Add(_person, p => p.Age == 19);</para> 
        /// </summary>
        /// <param name="t">泛型</param>
        /// <param name="match">委托</param>
        public void Add(T t, Predicate<T> match)
        {
            if (match != null)
            {
                T _finded = Find(match);
                if (_finded != null)
                {
                    Remove(_finded);
                }
                Add(t);
            }
        }
        #endregion
    }
}